﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Input;

namespace TouchUmlUI
{
    public static class SignalR
    {

        public static Window1 windowParent;
        private static bool cc = true;

        public static UMLObj findUmlObjByElement(Diagram.ElementNaDiagramie end, OurCanvas ac)
        {
            foreach (UMLObj item in ac.al)
            {
                if (item.guml.obj_uml.Nazwa == null) continue;
                if (item.guml.obj_uml.Nazwa.CompareTo(end.Nazwa) == 0)
                    return item;
            }
            return null;
        }

        public static UMLObj findUmlObjByCanvas(Canvas aarg)
        {
            foreach (UMLObj item in windowParent.active_canvas.al)
            {
                if (item.guml.panel == aarg)
                {
                    return item;
                }
            }
            return null;
        }

        public static void onStylusEnter(object sender, StylusEventArgs sArgs)
        {
            if (sender is Canvas)
            {
                UMLObj umlObj = findUmlObjByCanvas(((Canvas)sender));
                if (umlObj != null)
                {
                    windowParent.activeUmlObj = umlObj;
                }
            }
        }

        public static void onMouseEnter(object sender, MouseEventArgs e)
        {
            if (sender is Canvas)
            {
                UMLObj umlObj = findUmlObjByCanvas(((Canvas)sender));
                if (umlObj != null)
                {
                    if (cc)
                    {
                        if (windowParent.can_click)
                        {
                            windowParent.activeUmlObj = umlObj;
                            windowParent.activeObj = umlObj;
                            if (windowParent.active_canvas.Children.Contains(windowParent.hintbox))
                            {
                                Console.WriteLine("Hiding!");
                                windowParent.hintbox.Hide(windowParent.active_canvas);
                                windowParent.hintbox = null;
                            }

                            UMLObj umlk = umlObj;
                            if (!((umlk is AktorObj) || (umlk is NotatkaObj) || (umlk is AkcjaObj)))
                            {
                                if (!SignalR.windowParent.active_canvas.Children.Contains(SignalR.windowParent.handWrite))
                                {
                                    windowParent.hintbox = new HintBoxClass(umlk.getX() + umlk.guml.panel.ActualWidth, umlk.getY() - 8, umlk);
                                    ((HintBoxClass)windowParent.hintbox).addButtonEventHandler(HintBoxClass.ButtonEvent.ROTATE, windowParent.obroc_Click);
                                    ((HintBoxClass)windowParent.hintbox).addButtonEventHandler(HintBoxClass.ButtonEvent.DELETE, windowParent.usun_Click);
                                    windowParent.active_canvas.Children.Add(windowParent.hintbox);
                                }
                            }
                        }
                    }
                    else
                    {
                        windowParent.activeUmlObj = umlObj;
                        windowParent.activeObj = umlObj;
                    }
                }
                cc = true;

            }
            else
            {
                Control dObj = sender as Control;
                if (dObj is OurListBox)
                {
                    OurListBox tmpListBox = (OurListBox)dObj;
                    onMouseEnter(((KlasaObj)tmpListBox.Tag).guml.panel, e);
                }
            }
        }

        public static void onMouseLeave(object sender, MouseEventArgs e)
        {
            //windowParent.associationHint.setShowing(false);
            // windowParent.transformObj = null;
            //windowParent.Title = sender.ToString();
            windowParent.activeUmlObj = null;
            windowParent.activeObj = null;
        }

        public static void onMouseMove(object sender, MouseEventArgs e)
        {
            cc = false;
            onMouseEnter(sender, e);
        }

        public static void onStylusButtonDown(object sender, StylusButtonEventArgs e)
        {
            System.Console.WriteLine("button down");
        }

        public static void onStylusButtonUp(object sender, StylusButtonEventArgs e)
        {
            System.Console.WriteLine("button up ");
        }

        public static void utworzAsocjacje(UMLType a_wybor, AssociableObj ref1, AssociableObj ref2, OurCanvas a_canvas, System.Windows.Ink.StrokeCollection lines)
        {
            if (a_wybor == UMLType.ASSOCIATION)
            {
                Console.WriteLine("Tworze asocjacje!");
                if (lines != null && lines.Count > 0)
                    a_canvas.Strokes.Remove(lines);
                GUML guml = new GUML(new Polozenie(0, 0, 200, 200), "asocjacja", a_wybor, a_canvas, ref1, ref2);
                UMLObj a_umlobj = a_canvas.dodajAsocjacje(a_wybor, ref1, ref2, guml);
                a_umlobj.lines = lines;
                guml.ustawUMLObj(a_umlobj);
                if (windowParent.Hint.Opacity == 1.0f)
                    a_umlobj.showHints(true);
                else
                    a_umlobj.showHints(false);
                windowParent.treeModelView.Refresh();
            }
        }

        public static GUML utworzObiekt(UMLType a_wybor, Polozenie a_polozenie, OurCanvas a_canvas, System.Windows.Ink.StrokeCollection lines)
        {
            return SignalR.utworzObiekt(a_wybor, a_polozenie, a_canvas, lines, true);
        }

        public static GUML utworzObiektZElementuDiagramu(OurCanvas c, UMLType wybor, Diagram.ElementNaDiagramie end)
        {
            Polozenie a_polozenie = new Polozenie(end.polozenie.X, end.polozenie.Y, end.rozmiar.Width, end.rozmiar.Height);
            GUML guml;
            UMLObj a_umlobj;
            if (end is Diagram.Asocjacja)
            {
                Diagram.Asocjacja aso = end as Diagram.Asocjacja;
                ModelUML.AsocjacjaUML.EndTypeEnum fromType = aso[0].EndType;
                ModelUML.AsocjacjaUML.EndTypeEnum toType = aso[1].EndType;
                String fromStr = aso[0].Tekst;
                String toStr = aso[1].Tekst;
                AssociableObj ref1 = findUmlObjByElement((Diagram.ElementNaDiagramie)aso[0].OwnedEnd, c) as AssociableObj;
                AssociableObj ref2 = findUmlObjByElement((Diagram.ElementNaDiagramie)aso[1].OwnedEnd, c) as AssociableObj;
                guml = new GUML(c, aso);
                a_umlobj = c.dodajAsocjacje(UMLType.ASSOCIATION, ref1, ref2, guml);
                ((Diagram.Asocjacja)guml.obj_uml)[0].EndType = fromType;
                ((Diagram.Asocjacja)guml.obj_uml)[1].EndType = toType;
                ((Diagram.Asocjacja)guml.obj_uml)[0].Tekst = fromStr;
                ((Diagram.Asocjacja)guml.obj_uml)[1].Tekst = toStr;
                ((AssociationObj)a_umlobj).setTextBlockPositions();
                ((AssociationObj)a_umlobj).updateEndings(true);
               /*if (windowParent.Hint.Opacity == 1.0f)
                    a_umlobj.showHints(true);
                else
                    a_umlobj.showHints(false);*/
                return guml;
            }
            else
            {
                guml = new GUML(a_polozenie, end.Nazwa, wybor, c, true);
                a_umlobj = c.dodajObiekt(wybor, a_polozenie, end.Nazwa, guml, true);

                // dodaj atrybuty do klasy
                if (wybor == UMLType.CLASS)
                {
                    Diagram.Klasa kl = (Diagram.Klasa)end;
                    for (int i = 0; i < kl.IloscAtrybutow; i++)
                    {
                        if (kl.GetAtrybut(i).ShowInGui) ((Diagram.Klasa)guml.obj_uml).GetAtrybut(i).ShowInGui = true;
                    }
                    for (int i = 0; i < kl.IloscOperacji; i++)
                    {
                        if (kl.GetOperacje(i).ShowInGui) ((Diagram.Klasa)guml.obj_uml).GetOperacje(i).ShowInGui = true;
                    }
                   
                }
                // dodaj operacje do interfejsu
                else if (wybor == UMLType.INTERFACE)
                {
                    Diagram.Interfejs kl = (Diagram.Interfejs)end;   
                    for (int i = 0; i < kl.IloscOperacji; i++)
                    {
                        if (kl.GetOperacje(i).ShowInGui) ((Diagram.Interfejs)guml.obj_uml).GetOperacje(i).ShowInGui = true;
                    }
                    /*
                    for (int i = 0; i < ((Diagram.Interfejs)end).IloscOperacji; i++)
                    {
                        Diagram.Operacja oper = ((Diagram.Interfejs)end).GetOperacje(i);
                        Diagram.Operacja nop = ((Diagram.Interfejs)guml.obj_uml).DodajOperacje(oper.Nazwa, oper.Typ.Nazwa);
                        for (int j = 0; j < nop.IloscAtrybutow; j++)
                        {
                            Diagram.Atrybut nopAttr = nop.GetAtrybut(j);
                            nop.DodajAtrybut(nopAttr);
                        }
                    }*/
                }
                else if (wybor == UMLType.ACTION)
                {
                    (a_umlobj as AkcjaObj).guml.panel.UpdateLayout();
                    (a_umlobj as AkcjaObj).Refresh();                    
                }
                else if (wybor == UMLType.NOTICE)
                {
                    ((Diagram.Notatka)guml.obj_uml).Tekst = ((Diagram.Notatka)end).Tekst;
                }
            }


            a_umlobj.lines = null;
            guml.panel.IsHitTestVisible = true;
            guml.ustawUMLObj(a_umlobj);
            guml.panel.MouseEnter += onMouseEnter;
            guml.panel.MouseLeave += onMouseLeave;
            guml.panel.MouseMove += onMouseMove;
            guml.panel.StylusEnter += onStylusEnter;
            guml.panel.StylusInAirMove += onStylusEnter;
            guml.panel.StylusButtonDown += onStylusButtonDown;
            guml.panel.StylusButtonUp += onStylusButtonUp;
            guml.panel.Tag = a_umlobj;
            a_umlobj.Refresh();
            ((UMLObj)a_umlobj).updateDependencyProperties();
            /*if (windowParent.Hint.Opacity == 1.0f)
                a_umlobj.showHints(true);
            else
                a_umlobj.showHints(false);*/
            return guml;
        }

        public static GUML utworzObiekt(UMLType a_wybor, Polozenie a_polozenie, OurCanvas a_canvas, System.Windows.Ink.StrokeCollection lines, bool addObj)
        {
            Random r = new Random();
            String a_name = "";

            if (a_wybor == UMLType.ACTION)
            {
                a_name = "Akcja " + Window1.object_counter;
            }
            else if (a_wybor == UMLType.ACTOR)
            {
                a_name = "Aktor " + Window1.object_counter;
            }
            else if (a_wybor == UMLType.CLASS)
            {
                a_name = "Klasa " + Window1.object_counter;
            }
            else if (a_wybor == UMLType.INTERFACE)
            {
                a_name = "Interfejs " + Window1.object_counter;
            }
            else if (a_wybor == UMLType.NOTICE)
            {
                a_name = "Notatka " + Window1.object_counter;
            }

            Window1.object_counter += 1;

            GUML guml = new GUML(a_polozenie, a_name, a_wybor, a_canvas, addObj);
            UMLObj a_umlobj = a_canvas.dodajObiekt(a_wybor, a_polozenie, a_name, guml, addObj);
            (a_umlobj.guml.obj_uml as Diagram.ElementNaDiagramie).polozenie.X = a_polozenie.x;
            (a_umlobj.guml.obj_uml as Diagram.ElementNaDiagramie).polozenie.Y = a_polozenie.y;
            (a_umlobj.guml.obj_uml as Diagram.ElementNaDiagramie).rozmiar.Width = a_polozenie.width;
            (a_umlobj.guml.obj_uml as Diagram.ElementNaDiagramie).rozmiar.Height = a_polozenie.height;
            a_umlobj.lines = lines;
            guml.panel.IsHitTestVisible = true;

            // MessageBox.Show(a_wybor + " "+addObj);
            if (addObj)
            {

            }

            guml.ustawUMLObj(a_umlobj);
            guml.panel.MouseEnter += onMouseEnter;
            guml.panel.MouseLeave += onMouseLeave;
            guml.panel.MouseMove += onMouseMove;
            guml.panel.StylusEnter += onStylusEnter;
            guml.panel.StylusInAirMove += onStylusEnter;
            guml.panel.StylusButtonDown += onStylusButtonDown;
            guml.panel.StylusButtonUp += onStylusButtonUp;
            guml.panel.Tag = a_umlobj;
            a_umlobj.Refresh();
            if (windowParent.Hint.Opacity == 1.0f)
                a_umlobj.showHints(true);
            else
                a_umlobj.showHints(false);
            if (addObj)
                windowParent.treeModelView.Refresh();
            return guml;
        }
    }

}
